package fr.upstlse.glre.server.controler;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.read.biff.BiffException;

import org.apache.commons.lang.StringUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import fr.upstlse.glre.business.ServiceLocator;
import fr.upstlse.glre.business.service.ActualiteService;
import fr.upstlse.glre.business.service.depot.DocumentService;
import fr.upstlse.glre.business.service.depot.LibelleService;
import fr.upstlse.glre.business.service.vitrine.PageVitrineService;
import fr.upstlse.glre.business.vo.ActualiteSearchCriteriaVO;
import fr.upstlse.glre.business.vo.ActualiteVO;
import fr.upstlse.glre.business.vo.depot.DocumentVO;
import fr.upstlse.glre.business.vo.depot.LibelleVO;
import fr.upstlse.glre.business.vo.user.UserVO;
import fr.upstlse.glre.business.vo.vitrine.PageVitrineVO;
import fr.upstlse.glre.client.constante.fields.LibelleConstante;
import fr.upstlse.glre.client.controler.ControlerService;
import fr.upstlse.glre.client.controler.RfgException;
import fr.upstlse.glre.client.controler.UserControlerService;
import fr.upstlse.glre.client.vo.actualite.ActualiteSearchCriteriaVOGWT;
import fr.upstlse.glre.client.vo.actualite.ActualiteVOGWT;
import fr.upstlse.glre.client.vo.depot.DocumentVOGWT;
import fr.upstlse.glre.client.vo.depot.LibelleVOGWT;
import fr.upstlse.glre.client.vo.user.UserVOGWT;
import fr.upstlse.glre.client.vo.vitrine.PageVitrineVOGWT;
import fr.upstlse.glre.server.util.VOUtil;
import fr.upstlse.glre.server.util.XlsReader;

public class ControlerServiceImpl extends RemoteServiceServlet implements
		ControlerService {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.getWriter().write("Wouhou");
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = -4162588882511003821L;

	private ServiceLocator serviceLocator;
	private DocumentService documentService;
	private LibelleService libelleService;
	private PageVitrineService pageVitrineService;
	private ActualiteService actualiteService;

	public ControlerServiceImpl() {
		serviceLocator = ServiceLocator.instance();
		documentService = serviceLocator.getDocumentService();
		libelleService = serviceLocator.getLibelleService();
		pageVitrineService = serviceLocator.getPageVitrineService();
		actualiteService = serviceLocator.getActualiteService();
	}

	public Long addDocument(DocumentVOGWT pDocument) {
		DocumentVO lDocumentVO = VOUtil.documentVOGWTTODocumentVO(pDocument);
		long lId = documentService.addDocument(lDocumentVO);

		return new Long(lId);
	}

	public Collection<DocumentVOGWT> getAllDocuments() {
		Collection<DocumentVO> lDocumentsVO = documentService.getAllDocuments();
		Collection<DocumentVOGWT> lDocumentsVOGWT = new ArrayList<DocumentVOGWT>(lDocumentsVO.size());

		for (DocumentVO lDocumentVO : lDocumentsVO) {
			lDocumentsVOGWT.add(VOUtil.documentVOTODocumentVOGWT(lDocumentVO));
		}

		return lDocumentsVOGWT;
	}

	public Collection<LibelleVOGWT> getAllLibelles() {
		Collection<LibelleVO> lLibellesVO = libelleService.getAllLibelle();
		ArrayList<LibelleVOGWT> lLibellesVOGWT = new ArrayList<LibelleVOGWT>(
				lLibellesVO.size());

		for (LibelleVO lLibelleVO : lLibellesVO) {
			lLibellesVOGWT.add(VOUtil.libelleVOToLibelleVOGWT(lLibelleVO));
		}

		return lLibellesVOGWT;
	}

	public PageVitrineVOGWT[] getAllPageVitrine() {
		PageVitrineVO[] lPageVitrinesVO = pageVitrineService
				.getAllPageVitrine();
		PageVitrineVOGWT[] lPageVitrinesVOGWT = new PageVitrineVOGWT[lPageVitrinesVO.length];

		int i = 0;
for (PageVitrineVO lPageVitrineVO : lPageVitrinesVO) {
			lPageVitrinesVOGWT[i] = VOUtil
					.pageVitrineVOToPageVitrineVOGWT(lPageVitrineVO);
			i++;
		}

		return lPageVitrinesVOGWT;
	}

	public Long createPageVitrine(PageVitrineVOGWT pageVitrineVOGWT) {
		PageVitrineVO lPageVitrineVO = VOUtil
				.pageVitrineVOGWTToPageVitrineVO(pageVitrineVOGWT);
		long lId = pageVitrineService.createPageVitrine(lPageVitrineVO);
		return new Long(lId);
	}

	public void updatePageVitrine(PageVitrineVOGWT pageVitrineVOGWT) {
		PageVitrineVO lPageVitrine = VOUtil
				.pageVitrineVOGWTToPageVitrineVO(pageVitrineVOGWT);
		pageVitrineService.updatePageVitrine(lPageVitrine);
	}

	public Long createLibelle(LibelleVOGWT libelleVOGWT) {
		LibelleVO lLibelleVO = VOUtil.libelleVOGWTToLibelleVO(libelleVOGWT);

		Long lId = libelleService.addLibelle(lLibelleVO);
		return lId;
	}

	public void deleteLibelle(LibelleVOGWT libelleVOGWT) {
		LibelleVO lLibelleVO = VOUtil.libelleVOGWTToLibelleVO(libelleVOGWT);
		libelleService.removeLibelle(lLibelleVO);
	}

	public void updateLibelle(LibelleVOGWT libelleVOGWT) {
		LibelleVO lLibelleVO = VOUtil.libelleVOGWTToLibelleVO(libelleVOGWT);
		libelleService.updateLibelle(lLibelleVO);
	}

	/**
	 * {@inheritDoc}
	 * The timetable is a document with "EMPLOI DU TEMPS" as libelle.
	 */
	public String getEmploiDuTemps() throws Throwable {
		LibelleVO lLibelleVO = libelleService.getByIntitule(LibelleConstante.EMPLOI_DU_TEMPS.getValue());
		if(lLibelleVO == null) {
			throw new RfgException("Libelle emploi du temps n'existe pas");
		}
		DocumentVO lDocumentVO = documentService.findByLibelle(lLibelleVO);
		if(lDocumentVO == null) {
			throw new RfgException("L'emploi du temps n'a pas pu être trouvé");
		}
		ByteArrayInputStream lIn = new ByteArrayInputStream(lDocumentVO
				.getContenu());
		String lXMLEmploiDuTemps = null;
		try {
			Workbook lWorkbook = Workbook.getWorkbook(lIn);
			StringWriter lStringWriter = new StringWriter();
			XlsReader lXMLDocument = new XlsReader(lWorkbook, lStringWriter);
			lXMLDocument.read();
			
			lXMLEmploiDuTemps = lXMLDocument.getWriter().toString();
		} catch (BiffException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return lXMLEmploiDuTemps;
	}

	public void deleteDocument(DocumentVOGWT documentVOGWT) {
		DocumentVO lDocumentVO = VOUtil.documentVOGWTTODocumentVO(documentVOGWT);
		documentService.removeDocument(lDocumentVO);
	}

	public void deleteDocument(long documentId) {
		DocumentVO lDocumentVO = documentService.getById(documentId);
		documentService.removeDocument(lDocumentVO);
	}

	public List<ActualiteVOGWT> findActualite(
			ActualiteSearchCriteriaVOGWT pActualiteSearchCriteriaVOGWT) {
		ActualiteSearchCriteriaVO lActualiteSearchCriteriaVO = VOUtil.createActualiteSearchCriteriaVO(pActualiteSearchCriteriaVOGWT);
		List<ActualiteVO> lActualiteVOs = actualiteService.findActualite(lActualiteSearchCriteriaVO);
		
		List<ActualiteVOGWT> lActualiteVOGWTs = new ArrayList<ActualiteVOGWT>(lActualiteVOs.size());
		for(ActualiteVO lActualiteVO : lActualiteVOs) {
			ActualiteVOGWT lActualiteVOGWT = VOUtil.createActualiteVOGWT(lActualiteVO);
			lActualiteVOGWTs.add(lActualiteVOGWT);
		}
		return lActualiteVOGWTs;
	}

	public Long createActualite(ActualiteVOGWT pActualiteVOGWT) {
		ActualiteVO lActualiteVO = VOUtil.createActualiteVO(pActualiteVOGWT);
		//Get user
		UserControlerService lUserControlerService = new UserControlerServiceImpl();
		UserVOGWT lUserVOGWT = lUserControlerService.getUserById(lActualiteVO.getUserVO().getId());
		UserVO lUserVO = VOUtil.userVOGWTToUserVO(lUserVOGWT);
		lActualiteVO.setUserVO(lUserVO);
		
		long lId = actualiteService.createActualite(lActualiteVO);
		return lId;
	}

	public List<ActualiteVOGWT> getAllActualite() {
		List<ActualiteVO> lActualiteVOs = actualiteService.getAllActualites();
		
		List<ActualiteVOGWT> lActualiteVOGWTs = new ArrayList<ActualiteVOGWT>(lActualiteVOs.size());
		for(ActualiteVO lActualiteVO : lActualiteVOs) {
			ActualiteVOGWT lActualiteVOGWT = VOUtil.createActualiteVOGWT(lActualiteVO);
			lActualiteVOGWTs.add(lActualiteVOGWT);
		}
		return lActualiteVOGWTs;
	}

	public void deleteActualite(long pId) {
		actualiteService.deleteActualite(pId);
	}

	public void updateActualite(ActualiteVOGWT pActualiteVOGWT) {
		ActualiteVO lActualiteVO = VOUtil.createActualiteVO(pActualiteVOGWT);
		//Get user
		if(StringUtils.isBlank(pActualiteVOGWT.getUserVOGWT().getLogin())) {
			UserControlerService lUserControlerService = new UserControlerServiceImpl();
			UserVOGWT lUserVOGWT = lUserControlerService.getUserById(lActualiteVO.getUserVO().getId());
			UserVO lUserVO = VOUtil.userVOGWTToUserVO(lUserVOGWT);
			lActualiteVO.setUserVO(lUserVO);
		}
		actualiteService.updateActualite(lActualiteVO);
	}
}